#pragma once
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "../Comm/Log.hpp"
#include "../Comm/Util.hpp"
namespace ns_compiler
{
    using namespace ns_util;
    using namespace ns_log;
    class Compiler
    {
    public:
        Compiler() {}
        ~Compiler() {}
        static bool Compile(const std::string &filename)
        {
            pid_t pid = fork();
            if (pid < 0)
            {
                LOG(ERROR) << "内部错误，创建子进程失败\n";
                return false;
            }
            if (pid == 0)
            {
                umask(0);
                // 子进0程
                int _stderrfd = open(Path_Util::compilerErr(filename).c_str(), O_CREAT | O_WRONLY, 0644);
                if (_stderrfd < 0)
                {
                    LOG(WARNING) << "创建.stderr文件失败\n";
                    exit(1);
                }
                dup2(_stderrfd, 2); // 重定向，文件描述符表不会受到程序替换影响
                // g++ -o src exe -std=c++11
                execlp("g++", "g++", "-o", Path_Util::Exe(filename).c_str(), Path_Util::Src(filename).c_str(), "-std=c++11","-D","COMPILER_ONLINE", nullptr /*不要忘记*/);
                LOG(FATAL) << "启动g++编译器失败\n";
                exit(2); // 程序替换失败，直接结束进程
            }

            // 父进程
            waitpid(pid, nullptr, 0);
            if (File_Util::isFileExist(Path_Util::Exe(filename)))
            {
                LOG(INFO) << Path_Util::Src(filename) << "编译成功!\n";
                return true;
            }
            LOG(INFO) << Path_Util::Src(filename) << "编译失败!\n";
            return false;
        }

    private:
    };
}
